package router

import (
	"net/http"
	"path/filepath"
	"time"

	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"

	"photowall/pkg/config"
	"photowall/pkg/log"
	"photowall/pkg/optiondef"
	"photowall/pkg/service"
	"photowall/pkg/utils"
)

func init() {
	photoWallRouteRegister()
}

func photoWallRouteRegister() {
	router := GetMainRouter()

	store := cookie.NewStore([]byte("secret_key")) // 使用一个密钥来加密 cookie
	router.Use(sessions.Sessions("my_session", store))

	router.GET("/test/", func(c *gin.Context) {
		c.JSON(http.StatusAccepted, gin.H{
			"hello": "test",
		})
	})

	// add
	router.POST("/photo_wall/album/addalbum/", checkWechatUserLoggedMiddleWare, addAlbumToUser)

	// get
	router.GET("/photowall/wxuser/userinfo/", checkWechatUserLoggedMiddleWare, getWxUserInfoRoute)
	router.GET("/photo_wall/album/getuseralbumsinfo/", checkWechatUserLoggedMiddleWare, getWxuserAlbumsInfo)
	router.GET("/photo_wall/album/getuseralbuminfo/", checkWechatUserLoggedMiddleWare, getUserAlbumInfo)

	// pub get
	router.GET("/photo_wall/album/getpubalbuminfo/", getPubAlbumInfo)

	// del
	router.DELETE("/photo_wall/album/deletealbum/", checkWechatUserLoggedMiddleWare, deleteUserAlbum)

	/************photo_service***************/
	// add
	router.POST("/photo_wall/photo/addphoto/", checkWechatUserLoggedMiddleWare, addPhotoToUser)

	// get
	router.GET("/photo_wall/pubphoto/:photo_name", getPubPhotoByName)
	router.GET("/photo_wall/photo/getalbumphotos/", getAlbumPhotos)

	//delete
	router.DELETE("/photo_wall/photo/delphoto/", deleteOnePhoto)

	// TODO: 真是一项超级繁琐的工作，虽然有点拼凑起来的感觉，设计有点欠缺考虑就开始实现了，但是大部分应该都至少能够正常使用了吧？
	// TODO: 接下来要干什么事情呢？
}

// 上传的照片信息
type uploadPhotoInfoStruct struct {
	// 相册名
	AlbumName string `json:"album_name"`
	// 相片描述
	Description string `json:"description"`
	// 文件的二进制内容
	FileBinary []byte `json:"file_binary"`
	// 文件格式
	FileType string `json:"file_type"`
	// 名称
	Name string `json:"name"`
}

func addPhotoToUser(c *gin.Context) {
	// 从请求中提取照片信息
	var uploadInfo uploadPhotoInfoStruct
	if err := c.ShouldBindJSON(&uploadInfo); err != nil {
		log.GetMainLogger().Error("Invalid photo data: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid upload data"})
		return
	}

	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userid, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user open_id from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user open_id from Redis"})
		return
	}

	// 从 Redis 中获取用户的 name
	userName, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUsernameMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user name from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user name from Redis"})
		return
	}

	// 校验 uploadInfo.AlbumName 是否存在数据库中，只有相册在数据库中才能进行添加照片
	exists, err := optiondef.GetPhotoWallService().IsAlbumExists(userid, uploadInfo.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to check album existence: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to check album existence"})
		return
	}
	if !exists {
		log.GetMainLogger().Error("Album does not exist")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Album does not exist"})
		return
	}

	// 写入文件到本地文件夹
	photoID := service.GetGuidForImage()
	filePath := filepath.Join(config.GetConfig().FileSaveConfig.ImageConfig.ImageSavePath, photoID)
	err = utils.SaveFile(uploadInfo.FileBinary, filePath)
	if err != nil {
		log.GetMainLogger().Error("Failed to save file: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to save file"})
		return
	}

	// 创建 Photoinfo 实例
	photo := optiondef.Photoinfo{
		Author:      userName,
		AuthorID:    userid,
		PhotoName:   uploadInfo.Name,
		PhotoID:     photoID,
		Description: uploadInfo.Description,
		Public:      0,
		URL:         photoID,
	}

	// 调用 AlbumService 的 AddAlbum 方法将照片信息添加到数据库中
	success, err := optiondef.GetPhotoWallService().AddPhotoToAlbumByAlbumID(uploadInfo.AlbumName, &photo)
	if err != nil {
		log.GetMainLogger().Error("Failed to add photo to database: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to add photo to database"})
		return
	}

	if !success {
		log.GetMainLogger().Error("Failed to add photo to database")
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to add photo to database"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": 200, "message": "Photo added successfully"})
}

// 从请求中提取相册信息
var uploadAlbumInfo struct {
	AlbumCoverURL string `json:"album_cover_url"`
	AlbumName     string `json:"album_name"`
	Description   string `json:"description"`
}

func addAlbumToUser(c *gin.Context) {
	if err := c.ShouldBindJSON(&uploadAlbumInfo); err != nil {
		log.GetMainLogger().Error("Invalid album data: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid album data"})
		return
	}

	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userid, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user open_id from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user open_id from Redis"})
		return
	}

	// 创建 AlbumInfo 实例
	album := optiondef.AlbumInfo{
		AlbumID:       service.GetGuidForAlbumID(), // 假设您有一个方法来生成唯一 ID
		AuthorID:      userid,
		AlbumName:     uploadAlbumInfo.AlbumName,
		CreateDate:    time.Now().Format(time.RFC3339), // 使用当前时间作为创建日期
		Description:   uploadAlbumInfo.Description,
		AlbumCoverURL: "", // 可以选择在相册创建时让其为空，或根据需要提供初始值
	}

	// 调用 AlbumService 的 AddAlbum 方法将新相册信息添加到数据库中
	success, err := optiondef.GetPhotoWallService().AddAlbum(userid, &album)
	if err != nil {
		log.GetMainLogger().Error("Failed to add album to database: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to add album to database"})
		return
	}

	if !success {
		log.GetMainLogger().Error("Failed to add album to database")
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to add album to database"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": 200, "message": "Album added successfully"})
}

// deleteUserAlbum handles the request to delete a user's album
func deleteUserAlbum(c *gin.Context) {
	// 定义一个结构体用于绑定请求体
	var req struct {
		AlbumName string `json:"album_name"`
	}

	// 绑定 JSON 请求体到结构体
	if err := c.ShouldBindJSON(&req); err != nil {
		log.GetMainLogger().Error("Invalid request body: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid request body"})
		return
	}

	// 校验相册名是否为空
	if req.AlbumName == "" {
		log.GetMainLogger().Error("Album name is required")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Album name is required"})
		return
	}

	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userID, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user open_id from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user open_id from Redis"})
		return
	}

	// 调用 AlbumService 的 DeleteAlbum 方法删除相册
	success, err := optiondef.GetPhotoWallService().DeleteAlbum(userID, req.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to delete album: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to delete album"})
		return
	}

	if !success {
		log.GetMainLogger().Error("Failed to delete album, it may not exist or you don't have permission")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Failed to delete album, it may not exist or you don't have permission"})
		return
	}

	// TODO: 还需要删除相册中的相片

	c.JSON(http.StatusOK, gin.H{"msg": 200, "message": "Album deleted successfully"})
}

func getWxuserAlbumsInfo(c *gin.Context) {
	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userID, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user open_id from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user open_id from Redis"})
		return
	}

	// 调用 AlbumService 的 GetUserAlbums 方法获取用户的相册信息
	albums, err := optiondef.GetPhotoWallService().GetAlbumsByAuthorID(userID)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user albums: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user albums"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": 200, "albums": albums})
}

// getPubAlbumInfo handles the request to get album information by album name
func getPubAlbumInfo(c *gin.Context) {
	// 定义一个结构体用于绑定请求体
	var req struct {
		AlbumName string `json:"album_name" binding:"required"`
	}

	// 绑定 JSON 请求体到结构体
	if err := c.ShouldBindJSON(&req); err != nil {
		log.GetMainLogger().Error("Invalid request body: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid request body"})
		return
	}

	// 校验相册名是否为空
	if req.AlbumName == "" {
		log.GetMainLogger().Error("Album name is required")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Album name is required"})
		return
	}

	// 调用 AlbumService 的 GetAlbumByName 方法获取相册信息
	album, err := optiondef.GetPhotoWallService().GetPubAlbumByName(req.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to get album information: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get album information"})
		return
	}

	if album == nil {
		log.GetMainLogger().Error("Album not found")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "Album not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": 200, "album": album})
}

func getUserAlbumInfo(c *gin.Context) {
	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userID, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user ID from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user ID from Redis"})
		return
	}

	// 定义一个结构体用于绑定请求体
	var req struct {
		AlbumName string `json:"album_name" binding:"required"`
	}

	// 绑定 JSON 请求体到结构体
	if err := c.ShouldBindJSON(&req); err != nil {
		log.GetMainLogger().Error("Invalid request body: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid request body"})
		return
	}

	// 校验相册名是否为空
	if req.AlbumName == "" {
		log.GetMainLogger().Error("Album name is required")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Album name is required"})
		return
	}

	// 调用 AlbumService 的 GetUserAlbumByName 方法获取用户相册信息
	album, err := optiondef.GetPhotoWallService().GetAlbumByAuthorIDAndAlbumName(userID, req.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user album information: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user album information"})
		return
	}

	if album == nil {
		log.GetMainLogger().Error("User album not found")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "User album not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": 200, "album": album})
}

func getPubPhotoByName(c *gin.Context) {
	// 从 URL 参数中获取 photo_name
	photoName := c.Param("photo_name")
	if photoName == "" {
		log.GetMainLogger().Error("Photo name is required")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Photo name is required"})
		return
	}

	// 调用 PhotoService 的 GetPublicPhotosByName 方法获取公开照片信息
	photos, err := optiondef.GetPhotoWallService().GetPublicPhotosByName(photoName)
	if err != nil {
		log.GetMainLogger().Error("Failed to get public photos by name: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get public photos by name"})
		return
	}

	if len(photos) == 0 {
		log.GetMainLogger().Error("Public photos not found")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "Public photos not found"})
		return
	}

	c.JSON(http.StatusOK, photos)
}

func getAlbumPhotos(c *gin.Context) {
	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userID, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user ID from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user ID from Redis"})
		return
	}

	// 定义一个结构体用于绑定请求体
	var req struct {
		AlbumName string `json:"album_name" binding:"required"`
	}

	// 绑定 JSON 请求体到结构体
	if err := c.ShouldBindJSON(&req); err != nil {
		log.GetMainLogger().Error("Invalid request body: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid request body"})
		return
	}

	// 校验相册名是否为空
	if req.AlbumName == "" {
		log.GetMainLogger().Error("Album name is required")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Album name is required"})
		return
	}

	// 调用 AlbumService 的 GetAlbumByAuthorIDAndAlbumName 方法获取用户相册信息
	album, err := optiondef.GetPhotoWallService().GetAlbumByAuthorIDAndAlbumName(userID, req.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user album information: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user album information"})
		return
	}

	if album == nil {
		log.GetMainLogger().Error("User album not found")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "User album not found"})
		return
	}

	// 调用 PhotoService 的 GetAllPhotosInAlbumByAlbumID 方法获取相册中的所有照片
	photos, err := optiondef.GetPhotoWallService().GetAllPhotosInAlbumByAlbumName(req.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to get photos in album: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get photos in album"})
		return
	}

	c.JSON(http.StatusOK, photos)
}

func deleteOnePhoto(c *gin.Context) {
	// 从 cookie 中获取 wx_session
	wxSession, err := c.Cookie(config.GetConfig().WechatUserConfig.RouteSession)
	if err != nil {
		log.GetMainLogger().Error("Failed to get wx_session from cookie: " + err.Error())
		c.JSON(http.StatusUnauthorized, gin.H{"msg": http.StatusUnauthorized, "error": "User not logged in"})
		return
	}

	// 从 Redis 中获取用户的 id
	userID, err := utils.GetFieldFromRedis(wxSession, config.GetConfig().WechatUserConfig.RedisUseridMark)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user ID from Redis: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user ID from Redis"})
		return
	}

	// 定义一个结构体用于绑定请求体
	var req struct {
		PhotoID   string `json:"photo_id" binding:"required"`
		AlbumName string `json:"album_name" binding:"required"`
	}

	// 绑定 JSON 请求体到结构体
	if err := c.ShouldBindJSON(&req); err != nil {
		log.GetMainLogger().Error("Invalid request body: " + err.Error())
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Invalid request body"})
		return
	}

	// 校验 photo_id 和 album_name 是否为空
	if req.PhotoID == "" || req.AlbumName == "" {
		log.GetMainLogger().Error("Photo ID and album name are required")
		c.JSON(http.StatusBadRequest, gin.H{"msg": http.StatusBadRequest, "error": "Photo ID and album name are required"})
		return
	}

	// 调用 AlbumService 的 GetAlbumByAuthorIDAndAlbumName 方法获取用户相册信息
	album, err := optiondef.GetPhotoWallService().GetAlbumByAuthorIDAndAlbumName(userID, req.AlbumName)
	if err != nil {
		log.GetMainLogger().Error("Failed to get user album information: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to get user album information"})
		return
	}

	if album == nil {
		log.GetMainLogger().Error("User album not found")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "User album not found"})
		return
	}

	// 检查用户是否拥有该照片
	isOwned, err := optiondef.GetPhotoWallService().IsPhotoOwnedByUser(req.PhotoID, userID)
	if err != nil {
		log.GetMainLogger().Error("Failed to check photo ownership: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to check photo ownership"})
		return
	}

	if !isOwned {
		log.GetMainLogger().Error("Photo not found or not owned by user")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "Photo not found or not owned by user"})
		return
	}

	// 调用 PhotoService 的 DeletePhotoByPhotoID 方法删除照片
	success, err := optiondef.GetPhotoWallService().DeletePhotoByPhotoID(req.PhotoID)
	if err != nil {
		log.GetMainLogger().Error("Failed to delete photo: " + err.Error())
		c.JSON(http.StatusInternalServerError, gin.H{"msg": http.StatusInternalServerError, "error": "Failed to delete photo"})
		return
	}

	if !success {
		log.GetMainLogger().Error("Photo not found or not owned by user")
		c.JSON(http.StatusNotFound, gin.H{"msg": http.StatusNotFound, "error": "Photo not found or not owned by user"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": 200, "success": true})
}
